package com.netflexitysolutions.amazonws.sdb.orm.internal.util;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.netflexitysolutions.amazonws.sdb.orm.metadata.AttributeMetadata;
import com.netflexitysolutions.amazonws.sdb.orm.metadata.IdMetadata;
import com.netflexitysolutions.amazonws.sdb.orm.metadata.ItemMetadata;

/**
 * @author MAX
 *
 */
public final class RecordUtil {
    
    /**
     * @param rec1
     * @param rec2
     * @return
     */
    public static <T> boolean equals(T rec1, T rec2) {
        if (rec1 == rec2)
            return true;
        if (rec1 == null || !rec1.getClass().equals(rec2.getClass()))
            return false;
        return rec2.toString().equals(rec1.toString());
    }

    /**
     * @param recordMetadata
     * @param record
     * @return
     */
    public static <T> String toString(ItemMetadata recordMetadata, T record) {
        StringBuffer buffer = new StringBuffer(128);
        buffer.append(recordMetadata.getName());
        buffer.append(StringConstants.PIPE);
        IdMetadata idMeta = recordMetadata.getId();
        if(idMeta != null){
        	buffer.append(idMeta.getName()).append(StringConstants.EQ).append(String.valueOf(idMeta.getFieldValue(record)));
        	buffer.append(StringConstants.PIPE);
        }
        for (AttributeMetadata fmd : recordMetadata.getAttributeMetadata()) {
            Object value = fmd.getFieldValue(record);
            if(value != null){
                buffer.append(fmd.getName()).append(StringConstants.EQ).append(String.valueOf(value));
            }
            buffer.append(StringConstants.PIPE);
        }
        return buffer.toString();
    }

    /**
     * @param recordMetadata
     * @param record
     * @return
     */
    public static <T> String toStringWithoutIDs(ItemMetadata recordMetadata, T record) {
        StringBuffer buffer = new StringBuffer(128);
        buffer.append(recordMetadata.getName());
        buffer.append(StringConstants.PIPE);
        for (AttributeMetadata fmd : recordMetadata.getAttributeMetadata()) {
            Object value = fmd.getFieldValue(record);
            if(value != null){
                buffer.append(fmd.getName()).append(StringConstants.EQ).append(String.valueOf(value));
            }
            buffer.append(StringConstants.PIPE);
        }
        return buffer.toString();
    }
    
    /**
     * @param recordMetadata
     * @param record
     * @return
     */
    public static <T> int hashCode(ItemMetadata recordMetadata, T record) {
        StringBuffer buffer = new StringBuffer(32);
        buffer.append(recordMetadata.getName());
        buffer.append(StringConstants.PIPE);
        IdMetadata idMeta = recordMetadata.getId();
        if(idMeta != null){
        	buffer.append(idMeta.getName()).append(StringConstants.EQ).append(String.valueOf(idMeta.getFieldValue(record)));
        	buffer.append(StringConstants.PIPE);
        }
        for (AttributeMetadata fmd : recordMetadata.getAttributeMetadata()) {
            Object value = fmd.getFieldValue(record);
            if(value != null){
                buffer.append(String.valueOf(value));
            }
            buffer.append(StringConstants.PIPE);
        }
        return (buffer.toString()).hashCode();
    }

    /**
     * @param records
     * @param columnName
     * @return
     */
    public static <T> Map<? extends Object,T> createRecordMap(ItemMetadata recordMetadata, List<T> records, String propertyName){
        if(records == null || records.isEmpty()){
            return Collections.emptyMap();
        }
        Map<Object, T> recMap = new HashMap<Object, T>(records.size());
        AttributeMetadata fieldMetadata = recordMetadata.getAttributeMetadataByName(propertyName);
        for (T rec : records) {
            recMap.put(fieldMetadata.getFieldValue(rec), rec);
        }
        return recMap;
    }
}
